/*
kunpengsecl licensed under the Mulan PSL v2.
You can use this software according to the terms and conditions of
the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at:
    http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.

Author: wucaijun
Create: 2021-10-08
Description: Using grpc to implement the rasService API.
	1. 2022-01-19	wucaijun
		redefine SendReportRequest parameters and refine some implementations.
	2. 2022-01-28	wucaijun
		fix the problem that grpc occupy all the file handle, use LimitListener
		and getSockNum to auto adjust the max limit of grpc socket handle.
	3. 2022-01-29	wucaijun
		add a new group communication functions to rac, these functions will try
	to use the same grpc socket to enhance performance if possible.

Notice:
	For performance, change the process max file limit and database max connections.
`ulimit -n 200000`			# set in the ras start bash script
`max_connections = 1000`	# in /var/lib/pgsql/data/postgresql.conf and restart
*/

package client

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/json"
	"encoding/pem"
	"io/ioutil"
	"math/big"
	"net"
	"os"
	"testing"
	"time"

	"gitee.com/openeuler/kunpengsecl/attestation/common/cryptotools"
	"gitee.com/openeuler/kunpengsecl/attestation/ras/clientapi"
	"gitee.com/openeuler/kunpengsecl/attestation/ras/clientapi/server"
	"gitee.com/openeuler/kunpengsecl/attestation/ras/config"
	"gitee.com/openeuler/kunpengsecl/attestation/ras/trustmgr"
)

const (
	EKpubPEM = `
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjNq/p49Xwi8UTqq+e+wr
nsXeDfHJjVrtjmAJZvIgrkuYkItllkIINnjPYxKll56kuYVQZoKmQYDMNXN4zWON
BQEko2azkwBdZnkkyFefTpfLY3t6njmO0go318vvrZ2EuPCOBAtWQ1YuxbdD0f+C
haCjLbpGAJJwfpvQnLWLriYstxISEMUoeY6j5XYl4rR84Y3EvNsTDTK/omnUUWUF
TLa9wCAmgcwTZQXakgvsyv/+v1c4yU3rxgn71XqhzYMK3wwzYzxUp5GEg9I5u6Vd
+F5Uys+gK4X5pByIIYwyc/HJYr7yYLTWIeN8Ovg+XOLq/X33CpwNXvf3LMoJCjBH
JwIDAQAB
-----END PUBLIC KEY-----`
	IKpubPEM = `
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn8CYQqdaTdMxnKp248Fb
UZhxmpSTbb5CA/wUQQ0ARzr0eV3VwzKUhf8mPzkZQDTh36MzGxviBOpk922Gq3Ou
g1OXZ2LG2FPelqQRMvdWY3P/ITzKCoJ+DxlSDAt2zNuXRPnn/TyhXLx8UIAf5Vsx
OjvRxfV/z4r7zcOf33FdI8SuLV3YpNo/pOTJwqv/egV0kxtHDmqI3Vus+KSRjg6g
mlFex7A5TP8axDyLz0nPYP7XLbx1xNQ58VE8Oe51k7qwv8TOE03FVkWkSY25OEH1
2fSx1FasGAEVXVeEugz2W49rLXH4g8DMQ46Q6340J/+oS7+zT1Z0wNDGkqyQD1st
FQIDAQAB
-----END PUBLIC KEY-----`
)

const serverConfig = `
database:
  host: localhost
  name: kunpengsecl
  password: postgres
  port: 5432
  user: postgres
log:
  file: ./logs/ras-log.txt
racconfig:
  digestalgorithm: sha1
  hbduration: 10s
  trustduration: 2m0s
rasconfig:
  authkeyfile: ./ecdsakey.pub
  pcakeycertfile: ""
  pcaprivkeyfile: ""
  restport: 127.0.0.1:40002
  rootkeycertfile: ""
  rootprivkeyfile: ""
  mgrstrategy: "auto"
  serialnumber: 0
  serverport: 127.0.0.1:40001
  onlineduration: 30s
  basevalue-extract-rules:
    manifest:
    - name:
      - 8-0
      - 80000008-1
      type: bios
    - name:
      - boot_aggregate
      - /etc/modprobe.d/tuned.conf
      type: ima
    pcrinfo:
      pcrselection:
      - 1
      - 2
      - 3
      - 4
`
const (
	configFilePath = "./config.yaml"
	BIOSLogPath    = "../../../rac/cmd/raagent/binary_bios_measurements"
	IMALogPath     = "../../../rac/cmd/raagent/ascii_runtime_measurements"
)

const (
	command                = 0x00008003
	constDNS               = "user=postgres password=postgres dbname=kunpengsecl host=localhost port=5432 sslmode=disable"
	constSaveKTACertFailed = "save KTA Cert failed %v"
	constsavekeyinfofailed = "save key information fail %v"
	constgetcachefailed    = "get cache by deviceId failed :%v"
	fileMod                = 0755
	keyMod                 = 0600
)

const (
	constDB = "postgres"
)

var (
	IKName = []byte{
		0x00, 0x0b, 0x25, 0x7f, 0x26, 0x0b, 0x02, 0x18, 0xf2, 0x15, 0xda, 0x02, 0xf9, 0xba, 0x7c, 0xf2, 0x68,
		0x15, 0x47, 0x80, 0x47, 0xa9, 0xaf, 0x60, 0x04, 0x88, 0x8e, 0x57, 0xfb, 0x34, 0x02, 0xd0, 0xf3, 0xf0}
	testquote = []byte{
		0xff, 0x54, 0x43, 0x47, 0x80, 0x18, 0x00, 0x22, 0x00, 0x0b, 0x12, 0x66, 0xfc, 0x6a, 0x0d, 0xdf, 0x97,
		0xb2, 0x9d, 0x01, 0x5d, 0xa0, 0xba, 0x65, 0x88, 0x02, 0x46, 0xfd, 0x6a, 0x6c, 0x07, 0xd4, 0x9f, 0x4a,
		0xd2, 0x15, 0xd8, 0x4c, 0x77, 0xf2, 0x74, 0x5d, 0x00, 0x20, 0x8f, 0xf2, 0x28, 0xf1, 0xbe, 0xe4, 0x63,
		0x0f, 0x6d, 0xe3, 0x52, 0xf0, 0xa0, 0x17, 0x8d, 0xc8, 0xd4, 0x48, 0x15, 0x06, 0xc1, 0x67, 0x51, 0xcd,
		0x50, 0x36, 0x87, 0xa5, 0x5f, 0xcf, 0xb8, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00,
		0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x17, 0x06, 0x19, 0x00, 0x16, 0x36, 0x36, 0x00,
		0x00, 0x00, 0x01, 0x00, 0x04, 0x03, 0xff, 0xff, 0xff, 0x00, 0x20, 0x3f, 0x27, 0x08, 0x3e, 0x20, 0xdb,
		0x7c, 0x0b, 0xf0, 0xe3, 0x16, 0x21, 0x19, 0x00, 0xa9, 0x0a, 0x53, 0xe9, 0x9e, 0xf1, 0x2a, 0x68, 0x62,
		0x2e, 0x89, 0x79, 0x27, 0x93, 0x59, 0x88, 0x03, 0xd2}
	testsignature = []byte{
		0x7b, 0x22, 0x41, 0x6c, 0x67, 0x22, 0x3a, 0x32, 0x30, 0x2c, 0x22, 0x52, 0x53, 0x41, 0x22, 0x3a, 0x7b,
		0x22, 0x48, 0x61, 0x73, 0x68, 0x41, 0x6c, 0x67, 0x22, 0x3a, 0x31, 0x31, 0x2c, 0x22, 0x53, 0x69, 0x67,
		0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x3a, 0x22, 0x47, 0x67, 0x30, 0x70, 0x78, 0x32, 0x47, 0x66,
		0x73, 0x38, 0x56, 0x32, 0x2b, 0x43, 0x77, 0x42, 0x2b, 0x6c, 0x55, 0x35, 0x78, 0x5a, 0x31, 0x55, 0x54,
		0x51, 0x6d, 0x36, 0x74, 0x55, 0x6e, 0x45, 0x43, 0x53, 0x44, 0x34, 0x59, 0x4b, 0x35, 0x34, 0x6a, 0x4e,
		0x32, 0x46, 0x49, 0x31, 0x52, 0x78, 0x4f, 0x6a, 0x58, 0x44, 0x79, 0x50, 0x63, 0x36, 0x4d, 0x47, 0x6e,
		0x67, 0x6e, 0x4c, 0x68, 0x2f, 0x4c, 0x31, 0x31, 0x46, 0x4e, 0x69, 0x6e, 0x49, 0x42, 0x30, 0x61, 0x55,
		0x53, 0x75, 0x63, 0x2f, 0x63, 0x6e, 0x76, 0x41, 0x52, 0x45, 0x41, 0x4a, 0x52, 0x50, 0x65, 0x39, 0x2b,
		0x42, 0x69, 0x50, 0x30, 0x69, 0x66, 0x6c, 0x53, 0x51, 0x45, 0x48, 0x6e, 0x63, 0x4d, 0x57, 0x30, 0x43,
		0x6d, 0x47, 0x6a, 0x42, 0x30, 0x6d, 0x30, 0x75, 0x43, 0x65, 0x77, 0x70, 0x63, 0x4d, 0x50, 0x73, 0x43,
		0x44, 0x4f, 0x52, 0x78, 0x4b, 0x4b, 0x2b, 0x4d, 0x4c, 0x35, 0x54, 0x38, 0x75, 0x4c, 0x4e, 0x65, 0x6d,
		0x4b, 0x58, 0x45, 0x50, 0x4f, 0x69, 0x36, 0x4c, 0x77, 0x49, 0x6b, 0x39, 0x38, 0x63, 0x6b, 0x64, 0x61,
		0x4f, 0x65, 0x76, 0x58, 0x39, 0x42, 0x62, 0x4c, 0x5a, 0x4e, 0x77, 0x7a, 0x51, 0x35, 0x4d, 0x42, 0x73,
		0x33, 0x6e, 0x50, 0x50, 0x48, 0x6c, 0x47, 0x39, 0x44, 0x70, 0x72, 0x68, 0x63, 0x6b, 0x67, 0x73, 0x44,
		0x48, 0x43, 0x75, 0x73, 0x72, 0x43, 0x34, 0x4b, 0x71, 0x5a, 0x48, 0x2f, 0x32, 0x39, 0x52, 0x54, 0x78,
		0x70, 0x58, 0x6d, 0x65, 0x39, 0x43, 0x4e, 0x50, 0x43, 0x6f, 0x6b, 0x61, 0x52, 0x6f, 0x70, 0x31, 0x77,
		0x77, 0x33, 0x54, 0x4e, 0x39, 0x79, 0x72, 0x5a, 0x68, 0x6d, 0x38, 0x55, 0x47, 0x47, 0x4b, 0x48, 0x66,
		0x55, 0x33, 0x59, 0x42, 0x63, 0x66, 0x77, 0x32, 0x57, 0x6f, 0x78, 0x36, 0x50, 0x58, 0x72, 0x61, 0x7a,
		0x48, 0x37, 0x52, 0x6a, 0x72, 0x66, 0x4b, 0x57, 0x62, 0x59, 0x69, 0x4b, 0x56, 0x79, 0x48, 0x67, 0x36,
		0x56, 0x4e, 0x45, 0x32, 0x4e, 0x4f, 0x75, 0x6d, 0x41, 0x76, 0x36, 0x54, 0x30, 0x58, 0x48, 0x78, 0x2b,
		0x39, 0x39, 0x53, 0x71, 0x6f, 0x58, 0x30, 0x6c, 0x6d, 0x39, 0x4a, 0x7a, 0x30, 0x39, 0x77, 0x53, 0x74,
		0x54, 0x59, 0x35, 0x33, 0x71, 0x66, 0x6d, 0x4e, 0x32, 0x31, 0x36, 0x41, 0x69, 0x32, 0x73, 0x57, 0x39,
		0x72, 0x66, 0x2b, 0x74, 0x70, 0x7a, 0x7a, 0x6a, 0x6a, 0x36, 0x67, 0x3d, 0x3d, 0x22, 0x7d, 0x2c, 0x22,
		0x45, 0x43, 0x43, 0x22, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x7d}
	testpcr = []byte{
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x30, 0x30, 0x0a, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x30, 0x31, 0x0a, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x30, 0x32, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x30, 0x33, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x73,
		0x68, 0x61, 0x31, 0x20, 0x30, 0x34, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x73, 0x68, 0x61,
		0x31, 0x20, 0x30, 0x35, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20,
		0x30, 0x36, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x30, 0x37,
		0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x30, 0x38, 0x0a, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x30, 0x39, 0x0a, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x31, 0x30, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x31, 0x31, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20,
		0x73, 0x68, 0x61, 0x31, 0x20, 0x31, 0x32, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x73, 0x68,
		0x61, 0x31, 0x20, 0x31, 0x33, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x73, 0x68, 0x61, 0x31,
		0x20, 0x31, 0x34, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x31,
		0x35, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x31, 0x36, 0x0a,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x31, 0x37, 0x0a, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x31, 0x38, 0x0a, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x31, 0x39, 0x0a, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x20, 0x73, 0x68, 0x61, 0x31, 0x20, 0x32, 0x30, 0x0a, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x20, 0x73,
		0x68, 0x61, 0x31, 0x20, 0x32, 0x31, 0x0a, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
		0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x20, 0x73, 0x68, 0x61,
		0x31, 0x20, 0x32, 0x32, 0x0a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
		0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x73, 0x68, 0x61, 0x31, 0x20,
		0x32, 0x33, 0x0a}
)

var (
	emptyClientInfoErr  = "create empty ClientInfo error"
	createClientInfoErr = "create test ClientInfo error"
	sendrRportErr       = "test SendReport error"
	testClientInfo      = map[string]string{"test name": "test value"}
)

func CreateServerConfigFile() {
	ioutil.WriteFile(configFilePath, []byte(serverConfig), 0644)
}

func RemoveConfigFile() {
	os.Remove(configFilePath)
}

func prepare() {
	CreateServerConfigFile()
	// config.InitFlags()
	config.LoadConfigs()
	config.HandleFlags()
}

func release() {
	RemoveConfigFile()
	RemoveFiles()
}

func createCert() []byte {
	max := new(big.Int).Lsh(big.NewInt(1), 128)
	serialNumber, err := rand.Int(rand.Reader, max)
	if err != nil {
		return nil
	}
	subject := pkix.Name{
		Organization: []string{"Company"},
		Country:      []string{"China"},
		CommonName:   "test ekcert",
	}

	Template := x509.Certificate{
		SerialNumber: serialNumber,
		Subject:      subject,
		NotBefore:    time.Now(),
		NotAfter:     time.Now().AddDate(10, 0, 0),
		KeyUsage:     x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign,
		ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
	}
	key, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		return nil
	}
	cert, err := x509.CreateCertificate(rand.Reader, &Template, &Template, &key.PublicKey, key)
	if err != nil {
		return nil
	}
	return cert
}

func RemoveFiles() {
	err := os.Remove("./pca-root.crt")
	if err != nil {
		return
	}
	err1 := os.Remove("./pca-root.key")
	if err1 != nil {
		return
	}
	err2 := os.Remove("./pca-ek.crt")
	if err2 != nil {
		return
	}
	err3 := os.Remove("./pca-ek.key")
	if err3 != nil {
		return
	}
	err4 := os.Remove("./https.crt")
	if err4 != nil {
		return
	}
	err5 := os.Remove("./https.key")
	if err5 != nil {
		return
	}
}

func GenRsaKey() (prvkey, pubkey []byte) {
	// 生成私钥文件
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		panic(err)
	}
	derStream := x509.MarshalPKCS1PrivateKey(privateKey)
	block := &pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: derStream,
	}
	prvkey = pem.EncodeToMemory(block)
	publicKey := &privateKey.PublicKey
	derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
	if err != nil {
		panic(err)
	}
	block = &pem.Block{
		Type:  "PUBLIC KEY",
		Bytes: derPkix,
	}
	pubkey = pem.EncodeToMemory(block)
	return
}

func TestDoClientapi(t *testing.T) {
	print("\nThis is in TestDoClientapi\n")
	trustmgr.CreateTrustManager(constDB, constDNS)
	defer trustmgr.ReleaseTrustManager()
	prepare()
	defer release()
	serverAddr := config.GetServerPort()

	go server.StartServer(serverAddr)
	defer server.StopServer()

	EKpubBlock, _ := pem.Decode([]byte(EKpubPEM))
	reqEC := clientapi.GenerateEKCertRequest{EkPub: EKpubBlock.Bytes}
	rspEC, err := DoGenerateEKCert(serverAddr, &reqEC)
	if err != nil {
		t.Errorf("test DoGenerateEKCert error %v", err)
	}
	IKpubBlock, _ := pem.Decode([]byte(IKpubPEM))
	_, err = DoGenerateIKCert(serverAddr, &clientapi.GenerateIKCertRequest{
		EkCert: rspEC.EkCert,
		IkPub:  IKpubBlock.Bytes,
		IkName: IKName,
	})
	if err != nil {
		t.Errorf("test DoGenerateIKCert error %v", err)
	}

	// test empty clientinfo
	ci, err := json.Marshal(map[string]string{})
	if err != nil {
		t.Error(emptyClientInfoErr)
	}
	r1, err := DoRegisterClient(serverAddr, &clientapi.RegisterClientRequest{
		Cert:       createCert(),
		ClientInfo: string(ci),
	})
	if err != nil {
		t.Errorf("test DoRegisterClient with empty clientinfo error %v", err)
	}

	// test empty request
	_, err = DoRegisterClient(serverAddr, &clientapi.RegisterClientRequest{})
	if err == nil {
		t.Errorf("test DoRegisterClient with empty request failed")
	}
	template := x509.Certificate{
		SerialNumber: big.NewInt(cryptotools.GetSerialNumber()),
		NotBefore:    time.Now(),
		NotAfter:     time.Now().AddDate(1, 0, 0),
		KeyUsage: x509.KeyUsageDigitalSignature |
			x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign,
		IsCA:           false,
		MaxPathLenZero: true,
		IPAddresses:    []net.IP{net.ParseIP(config.GetIP())},
	}
	ikCertDer, _ := cryptotools.GenerateCertificate(&template,
		config.GetPcaKeyCert(), IKpubBlock.Bytes, config.GetPcaPrivateKey())

	ci, err = json.Marshal(testClientInfo)
	if err != nil {
		t.Error(createClientInfoErr)
	}
	r2, err := DoRegisterClient(serverAddr, &clientapi.RegisterClientRequest{
		Cert:       ikCertDer,
		ClientInfo: string(ci),
	})
	if err != nil {
		t.Errorf("test DoRegisterClient error %v", err)
	}

	// test empty clientId
	_, err = DoSendHeartbeat(serverAddr, &clientapi.SendHeartbeatRequest{})
	if err != nil {
		t.Errorf("test DoSendHeartbeat with empty ClientId failed")
	}

	HBrep, err := DoSendHeartbeat(serverAddr, &clientapi.SendHeartbeatRequest{ClientId: r2.GetClientId()})
	if err != nil {
		t.Errorf("test DoSendHeartbeat error %v", err)
	}

	// test empty report
	srRep, _ := DoSendReport(serverAddr, &clientapi.SendReportRequest{})
	if srRep.GetResult() {
		t.Errorf("test DoSendReport with empty report failed")
	}

	testbios, err := ioutil.ReadFile(BIOSLogPath)
	if err != nil {
		t.Errorf("ReadFile error %v", err)
	}
	testima, err := ioutil.ReadFile(IMALogPath)
	if err != nil {
		t.Errorf("ReadFile error %v", err)
	}
	srRep, _ = DoSendReport(serverAddr, &clientapi.SendReportRequest{
		ClientId:   r2.GetClientId(),
		Nonce:      HBrep.ClientConfig.Nonce,
		ClientInfo: string(ci),
		Quoted:     testquote,
		Signature:  testsignature,
		Manifests: []*clientapi.Manifest{
			0: {Key: "pcr", Value: testpcr},
			1: {Key: "bios", Value: testbios},
			2: {Key: "ima", Value: testima},
		},
	})
	if !srRep.GetResult() {
		t.Errorf(sendrRportErr)
	}
	_, err = DoUnregisterClient(serverAddr, &clientapi.UnregisterClientRequest{})
	if err != nil {
		t.Errorf("test DoUnregisterClient with empty clientId failed %v", err)
	}

	_, err = DoUnregisterClient(serverAddr, &clientapi.UnregisterClientRequest{
		ClientId: r2.GetClientId(),
	})
	if err != nil {
		t.Errorf("test DoUnregisterClient error %v", err)
	}
	trustmgr.DeleteClientByID(r2.GetClientId())
	trustmgr.DeleteReportByID(r2.GetClientId())
	trustmgr.DeleteClientByID(r1.GetClientId())

	print("\nThis is in TestClientapiWithConn\n")

	ras, err := CreateConn(serverAddr)
	if err != nil {
		t.Errorf("fail to Create connection, %v", err)
	}
	defer ReleaseConn(ras)

	EKpubBlock, _ = pem.Decode([]byte(EKpubPEM))
	reqEC = clientapi.GenerateEKCertRequest{
		EkPub: EKpubBlock.Bytes,
	}
	rspEC, err = DoGenerateEKCertWithConn(ras, &reqEC)
	if err != nil {
		t.Errorf("test DoGenerateEKCertWithConn error %v", err)
	}
	IKpubBlock, _ = pem.Decode([]byte(IKpubPEM))
	_, err = DoGenerateIKCertWithConn(ras, &clientapi.GenerateIKCertRequest{
		EkCert: rspEC.EkCert,
		IkPub:  IKpubBlock.Bytes,
		IkName: IKName,
	})
	if err != nil {
		t.Errorf("test DoGenerateIKCertWithConn error %v", err)
	}

	// test empty clientinfo
	ci, err = json.Marshal(map[string]string{})
	if err != nil {
		t.Error(emptyClientInfoErr)
	}
	r1, err = DoRegisterClientWithConn(ras, &clientapi.RegisterClientRequest{
		Cert:       createCert(),
		ClientInfo: string(ci),
	})
	if err != nil {
		t.Errorf("test DoRegisterClientWithConn with empty clientinfo error %v", err)
	}
	defer trustmgr.DeleteClientByID(r1.GetClientId())

	// test empty request
	_, err = DoRegisterClientWithConn(ras, &clientapi.RegisterClientRequest{})
	if err == nil {
		t.Errorf("test DoRegisterClientWithConn with empty request failed")
	}
	template = x509.Certificate{
		SerialNumber: big.NewInt(cryptotools.GetSerialNumber()),
		NotBefore:    time.Now(),
		NotAfter:     time.Now().AddDate(1, 0, 0),
		KeyUsage: x509.KeyUsageDigitalSignature |
			x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign,
		IsCA:           false,
		MaxPathLenZero: true,
		IPAddresses:    []net.IP{net.ParseIP(config.GetIP())},
	}
	ikCertDer, _ = cryptotools.GenerateCertificate(&template,
		config.GetPcaKeyCert(), IKpubBlock.Bytes, config.GetPcaPrivateKey())

	ci, err = json.Marshal(testClientInfo)
	if err != nil {
		t.Error(createClientInfoErr)
	}
	r2, err = DoRegisterClientWithConn(ras, &clientapi.RegisterClientRequest{
		Cert:       ikCertDer,
		ClientInfo: string(ci),
	})
	if err != nil {
		t.Errorf("test DoRegisterClientWithConn error %v", err)
	}
	_, err = DoSendHeartbeatWithConn(ras, &clientapi.SendHeartbeatRequest{ClientId: r2.GetClientId()})
	if err != nil {
		t.Errorf("test DoSendHeartbeatWithConn error %v", err)
	}

	// test empty clientId
	_, err = DoSendHeartbeatWithConn(ras, &clientapi.SendHeartbeatRequest{})
	if err != nil {
		t.Errorf("test SendHeartbeatWithConn with empty ClientId failed")
	}

	HBrep, err = DoSendHeartbeatWithConn(ras, &clientapi.SendHeartbeatRequest{ClientId: r2.GetClientId()})
	if err != nil {
		t.Errorf("test SendHeartbeatWithConn error %v", err)
	}

	// test empty report
	srRep, _ = DoSendReportWithConn(ras, &clientapi.SendReportRequest{})
	if srRep.GetResult() {
		t.Errorf("test DoSendReportWithConn with empty report failed")
	}

	testbios, err = ioutil.ReadFile(BIOSLogPath)
	if err != nil {
		t.Errorf("ReadFile error %v", err)
	}
	testima, err = ioutil.ReadFile(IMALogPath)
	if err != nil {
		t.Errorf("ReadFile error %v", err)
	}
	srRep, _ = DoSendReportWithConn(ras, &clientapi.SendReportRequest{
		ClientId:   r2.GetClientId(),
		Nonce:      HBrep.ClientConfig.Nonce,
		ClientInfo: string(ci),
		Quoted:     testquote,
		Signature:  testsignature,
		Manifests: []*clientapi.Manifest{
			0: {Key: "pcr", Value: testpcr},
			1: {Key: "bios", Value: testbios},
			2: {Key: "ima", Value: testima},
		},
	})
	if !srRep.GetResult() {
		t.Errorf(sendrRportErr)
	}

	// test empty clientId
	_, err = DoUnregisterClientWithConn(ras, &clientapi.UnregisterClientRequest{})
	if err != nil {
		t.Errorf("test DoUnregisterClientWithConn with empty clientId failed %v", err)
	}

	_, err = DoUnregisterClientWithConn(ras, &clientapi.UnregisterClientRequest{
		ClientId: r2.GetClientId(),
	})
	if err != nil {
		t.Errorf("test DoUnregisterClientWithConn error %v", err)
	}
	defer trustmgr.DeleteClientByID(r2.GetClientId())
	defer trustmgr.DeleteReportByID(r2.GetClientId())
}
